package com.example.cms.Payments;
import com.example.cms.DB.DBUtil;
import com.example.cms.Users.User;
import com.example.cms.Appointments.*;
import java.sql.*;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class PaymentManager {

    private Scanner scanner;
    private Appointment appointment;
    private AppointmentsManager appointmentsManager;
    private Payment payment;
    private User currentUser;

    // 日期时间格式化器
    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    public PaymentManager() {
        this.scanner = new Scanner(System.in);
    }
    // ==================== 支付管理 ====================
    public void showPaymentMenu() {
        while (true) {
            System.out.println("\n--- 支付管理 ---");
            System.out.println("1. 创建支付");
            System.out.println("2. 查看支付详情");
            System.out.println("3. 处理支付");
            System.out.println("4. 查看支付历史");
            System.out.println("0. 返回主菜单");

            System.out.print("请选择操作: ");
            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    createPayment();
                    break;
                case "2":
                    viewPayment();
                    break;
                case "3":
                    processPayment();
                    break;
                case "4":
                    viewPaymentHistory();
                    break;
                case "0":
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    private void createPayment() {
        System.out.println("\n--- 创建支付 ---");
        try {
            System.out.print("预约ID: ");
            int appointmentId = Integer.parseInt(scanner.nextLine());

            Appointment appointment = appointmentsManager.findAppointmentById(appointmentId);
            if (appointment == null) {
                System.out.println("预约不存在！");
                return;
            }

            System.out.println("请选择支付方式:");
            System.out.println("1. 现金 (CASH)");
            System.out.println("2. 银行卡 (CARD)");
            System.out.println("3. 支付宝 (ALIPAY)");
            System.out.println("4. 微信 (WECHAT)");
            System.out.println("5. 保险 (INSURANCE)");
            System.out.print("请输入选择(1-5): ");
            String choice = scanner.nextLine();

            String paymentMethod = getPaymentMethodByChoice(choice);
            if (paymentMethod == null) {
                System.out.println("无效的选择！");
                return;
            }

            Payment payment = new Payment(appointmentId, appointment.getFeeAmount(), paymentMethod);
            payment.setPayerName(appointment.getPatientName());

            if (addPayment(payment)) {
                System.out.println("支付创建成功！支付号: " + payment.getPaymentNo());
            } else {
                System.out.println("支付创建失败！");
            }
        } catch (Exception e) {
            System.out.println("创建失败: " + e.getMessage());
        }
    }

    private String getPaymentMethodByChoice(String choice) {
        switch (choice) {
            case "1": return "CASH";
            case "2": return "CARD";
            case "3": return "ALIPAY";
            case "4": return "WECHAT";
            case "5": return "INSURANCE";
            default: return null;
        }
    }

    private void viewPayment() {
        System.out.println("\n--- 查看支付详情 ---");
        System.out.print("请输入支付ID: ");
        int paymentId = Integer.parseInt(scanner.nextLine());

        try {
            Payment payment = findPaymentById(paymentId);
            if (payment != null) {
                displayPaymentInfo(payment);
            } else {
                System.out.println("未找到支付信息！");
            }
        } catch (Exception e) {
            System.out.println("查询失败: " + e.getMessage());
        }
    }

    private void processPayment() {
        System.out.println("\n--- 处理支付 ---");
        System.out.print("请输入支付ID: ");
        int paymentId = Integer.parseInt(scanner.nextLine());

        try {
            Payment payment = findPaymentById(paymentId);
            if (payment == null) {
                System.out.println("支付记录不存在！");
                return;
            }

            System.out.print("交易号: ");
            String transactionNo = scanner.nextLine();

            payment.setTransactionNo(transactionNo);
            payment.setPaymentStatus("SUCCESS");

            if (updatePayment(payment)) {
                // 更新预约支付状态
                updateAppointmentPaymentStatus(payment.getAppointmentId(), "PAID");
                System.out.println("支付处理成功！");
            } else {
                System.out.println("支付处理失败！");
            }
        } catch (Exception e) {
            System.out.println("处理失败: " + e.getMessage());
        }
    }

    private void viewPaymentHistory() {
        System.out.println("\n--- 查看支付历史 ---");
        System.out.print("请输入预约ID: ");
        int appointmentId = Integer.parseInt(scanner.nextLine());

        try {
            List<Payment> payments = getPaymentsByAppointment(appointmentId);
            if (payments.isEmpty()) {
                System.out.println("暂无支付记录");
                return;
            }

            System.out.println("支付号\t金额\t方式\t状态\t时间");
            System.out.println("------------------------------------------------");
            for (Payment payment : payments) {
                String paymentTime = payment.getPaymentTime() != null ?
                        payment.getPaymentTime().format(dateTimeFormatter) : "未支付";
                System.out.printf("%s\t%.2f\t%s\t%s\t%s\n",
                        payment.getPaymentNo(),
                        payment.getAmount(),
                        payment.getPaymentMethod(),
                        payment.getPaymentStatus(),
                        paymentTime);
            }
        } catch (Exception e) {
            System.out.println("获取支付历史失败: " + e.getMessage());
        }
    }

    private void displayPaymentInfo(Payment payment) {
        System.out.println("\n=== 支付信息 ===");
        System.out.println("支付ID: " + payment.getPaymentId());
        System.out.println("支付号: " + payment.getPaymentNo());
        System.out.println("预约ID: " + payment.getAppointmentId());
        System.out.println("金额: " + payment.getAmount());
        System.out.println("支付方式: " + payment.getPaymentMethod());
        System.out.println("支付状态: " + payment.getPaymentStatus());
        System.out.println("支付时间: " + payment.getPaymentTime());
        System.out.println("支付人: " + payment.getPayerName());
    }

    // 支付相关操作方法
    private boolean addPayment(Payment payment) {
        String sql = "INSERT INTO payments (appointment_id, payment_no, amount, payment_method, " +
                "payment_status, transaction_no, payment_time, payer_name) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            pstmt.setInt(1, payment.getAppointmentId());
            pstmt.setString(2, payment.getPaymentNo());
            pstmt.setDouble(3, payment.getAmount());
            pstmt.setString(4, payment.getPaymentMethod());
            pstmt.setString(5, payment.getPaymentStatus());
            pstmt.setString(6, payment.getTransactionNo());
            pstmt.setTimestamp(7, payment.getPaymentTime() != null ?
                    Timestamp.valueOf(payment.getPaymentTime()) : null);
            pstmt.setString(8, payment.getPayerName());

            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                try (ResultSet rs = pstmt.getGeneratedKeys()) {
                    if (rs.next()) {
                        payment.setPaymentId(rs.getInt(1));
                    }
                }

                // 更新预约的支付状态
                if ("SUCCESS".equals(payment.getPaymentStatus())) {
                    updateAppointmentPaymentStatus(payment.getAppointmentId(), "PAID");
                }
                return true;
            }
        } catch (SQLException e) {
            System.err.println("添加支付记录失败: " + e.getMessage());
        }
        return false;
    }

    private Payment findPaymentById(int paymentId) {
        String sql = "SELECT p.*, a.appointment_no, pat.name as patient_name " +
                "FROM payments p " +
                "JOIN appointments a ON p.appointment_id = a.appointment_id " +
                "JOIN patients pat ON a.patient_id = pat.patient_id " +
                "WHERE p.payment_id = ?";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, paymentId);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapResultSetToPayment(rs);
                }
            }
        } catch (SQLException e) {
            System.err.println("查询支付记录失败: " + e.getMessage());
        }
        return null;
    }

    private boolean updatePayment(Payment payment) {
        String sql = "UPDATE payments SET appointment_id = ?, payment_no = ?, amount = ?, " +
                "payment_method = ?, payment_status = ?, transaction_no = ?, payment_time = ?, " +
                "payer_name = ? WHERE payment_id = ?";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, payment.getAppointmentId());
            pstmt.setString(2, payment.getPaymentNo());
            pstmt.setDouble(3, payment.getAmount());
            pstmt.setString(4, payment.getPaymentMethod());
            pstmt.setString(5, payment.getPaymentStatus());
            pstmt.setString(6, payment.getTransactionNo());
            pstmt.setTimestamp(7, payment.getPaymentTime() != null ?
                    Timestamp.valueOf(payment.getPaymentTime()) : null);
            pstmt.setString(8, payment.getPayerName());
            pstmt.setInt(9, payment.getPaymentId());

            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("更新支付记录失败: " + e.getMessage());
        }
        return false;
    }

    private List<Payment> getPaymentsByAppointment(int appointmentId) {
        List<Payment> payments = new ArrayList<>();
        String sql = "SELECT p.*, a.appointment_no, pat.name as patient_name " +
                "FROM payments p " +
                "JOIN appointments a ON p.appointment_id = a.appointment_id " +
                "JOIN patients pat ON a.patient_id = pat.patient_id " +
                "WHERE p.appointment_id = ? ORDER BY p.create_time DESC";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, appointmentId);
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    payments.add(mapResultSetToPayment(rs));
                }
            }
        } catch (SQLException e) {
            System.err.println("获取预约支付记录失败: " + e.getMessage());
        }
        return payments;
    }

    private boolean updateAppointmentPaymentStatus(int appointmentId, String paymentStatus) {
        String sql = "UPDATE appointments SET payment_status = ? WHERE appointment_id = ?";

        try (   Connection conn = DBUtil.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, paymentStatus);
            pstmt.setInt(2, appointmentId);

            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("更新预约支付状态失败: " + e.getMessage());
        }
        return false;
    }
    private Payment mapResultSetToPayment(ResultSet rs) throws SQLException {
        Payment payment = new Payment();
        payment.setPaymentId(rs.getInt("payment_id"));
        payment.setAppointmentId(rs.getInt("appointment_id"));
        payment.setPaymentNo(rs.getString("payment_no"));
        payment.setAmount(rs.getDouble("amount"));
        payment.setPaymentMethod(rs.getString("payment_method"));
        payment.setPaymentStatus(rs.getString("payment_status"));
        payment.setTransactionNo(rs.getString("transaction_no"));
        payment.setPaymentTime(rs.getTimestamp("payment_time") != null ?
                rs.getTimestamp("payment_time").toLocalDateTime() : null);
        payment.setPayerName(rs.getString("payer_name"));

        return payment;
    }



    public void setAppointmentsManager(AppointmentsManager appointmentsManager) {
        this.appointmentsManager = appointmentsManager;
    }
    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }

}
